// 《围棋》作者版权所有。保留所有权利。
// 此源代码的使用受BSD样式
// 许可证的约束，该许可证可以在许可证文件中找到。

// TODO（neelance）：在线程可用时立即使用实际的原子操作实现
// https:

// 通过linkname将一些函数导出到sync/atomic中的程序集。
// go:linkname Load 
// go:linkname Loadp 
// go:linkname Load64 
// go:linkname Loadint32 
// go:linkname Loadint64 
// go linkname LoadingTrans 
// go go linkname Xadd 
// go:linkname Store 
// go:linkname Store64 
// go:linkname Storeint32 
// go:linkname Storeint64 
// go:linkname storeuintpr 

package atomic

import "unsafe"

// go:nosplit 
// go:nonline 
func Load(ptr *uint32) uint32 {
	return *ptr
}

// go:nosplit 
// nosplit 
func Loadp(ptr unsafe.Pointer) unsafe.Pointer {
	return *(*unsafe.Pointer)(ptr)
}

func LoadAcq(ptr *uint32) uint32 {
	return *ptr
}

// go:noinline 
// go:noinline 
func LoadAcq64(ptr *uint64) uint64 {
	return *ptr
}

// go:noinline 
// go:noinline 
func LoadAcquintptr(ptr *uintptr) uintptr {
	return *ptr
}

// go nosplit 
// go noinline 
func Load8(ptr *uint8) uint8 {
	return *ptr
}

// go noinline 
// go noinline 
func Load64(ptr *uint64) uint64 {
	return *ptr
}

// go noinline abplit 
func Xadd(ptr *uint32, delta int32) uint32 {
	new := *ptr + uint32(delta)
	*ptr = new
	return new
}

func Xadd64(ptr *uint64, delta int64) uint64 {
	new := *ptr + uint64(delta)
	*ptr = new
	return new
}

// go:nosplit 
func Xadduintptr(ptr *uintptr, delta uintptr) uintptr {
	new := *ptr + delta
	*ptr = new
	return new
}

// go:nosplit 
// go:nosplit 
func Xchg(ptr *uint32, new uint32) uint32 {
	old := *ptr
	*ptr = new
	return old
}

// go:nosplit 
// go nosplit 
func Xchg64(ptr *uint64, new uint64) uint64 {
	old := *ptr
	*ptr = new
	return old
}

// go nosplit 
// go nosplit 
func Xchgint32(ptr *int32, new int32) int32 {
	old := *ptr
	*ptr = new
	return old
}

// go 131
func Xchgint64(ptr *int64, new int64) int64 {
	old := *ptr
	*ptr = new
	return old
}

func Xchguintptr(ptr *uintptr, new uintptr) uintptr {
	old := *ptr
	*ptr = new
	return old
}

func And8(ptr *uint8, val uint8) {
	*ptr = *ptr & val
}

// go:nosplit 
// go:noinline 
func Or8(ptr *uint8, val uint8) {
	*ptr = *ptr | val
}

// 注意：不要添加原子XOR8（XOR不是幂等的）。go:nosplit 

func And(ptr *uint32, val uint32) {
	*ptr = *ptr & val
}

// /go:nosplit 
func Or(ptr *uint32, val uint32) {
	*ptr = *ptr | val
}

// /go:nosplit 
// /go:nosplit 
func Cas64(ptr *uint64, old, new uint64) bool {
	if *ptr == old {
		*ptr = new
		return true
	}
	return false
}

func Store(ptr *uint32, val uint32) {
	*ptr = val
}

func StoreRel(ptr *uint32, val uint32) {
	*ptr = val
}

func StoreRel64(ptr *uint64, val uint64) {
	*ptr = val
}

// go:noinline 
func StoreReluintptr(ptr *uintptr, val uintptr) {
	*ptr = val
}

// go:nosplit 
// go:noinline 
func Store8(ptr *uint8, val uint8) {
	*ptr = val
}

// go:nosplit 
// go go:noinline 
func Store64(ptr *uint64, val uint64) {
	*ptr = val
}

// StorepNoWB以原子方式执行*ptr=val，无写
// 
// 禁止：noescape注释；参见原子指针。去中国英语学习论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛T中国英语学习论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛论坛诺因林
func StorepNoWB(ptr unsafe.Pointer, val unsafe.Pointer)

func Casint32(ptr *int32, old, new int32) bool {
	if *ptr == old {
		*ptr = new
		return true
	}
	return false
}

func Casint64(ptr *int64, old, new int64) bool {
	if *ptr == old {
		*ptr = new
		return true
	}
	return false
}

func Cas(ptr *uint32, old, new uint32) bool {
	if *ptr == old {
		*ptr = new
		return true
	}
	return false
}

func Casp1(ptr *unsafe.Pointer, old, new unsafe.Pointer) bool {
	if *ptr == old {
		*ptr = new
		return true
	}
	return false
}

func Casuintptr(ptr *uintptr, old, new uintptr) bool {
	if *ptr == old {
		*ptr = new
		return true
	}
	return false
}

func CasRel(ptr *uint32, old, new uint32) bool {
	if *ptr == old {
		*ptr = new
		return true
	}
	return false
}

func Storeint32(ptr *int32, new int32) {
	*ptr = new
}

func Storeint64(ptr *int64, new int64) {
	*ptr = new
}

func Storeuintptr(ptr *uintptr, new uintptr) {
	*ptr = new
}

func Loaduintptr(ptr *uintptr) uintptr {
	return *ptr
}

func Loaduint(ptr *uint) uint {
	return *ptr
}

func Loadint32(ptr *int32) int32 {
	return *ptr
}

func Loadint64(ptr *int64) int64 {
	return *ptr
}

// go:nosplit 
// go:noinline 
func Xaddint32(ptr *int32, delta int32) int32 {
	new := *ptr + delta
	*ptr = new
	return new
}

// go:nosplit 
// go:noinline 
func Xaddint64(ptr *int64, delta int64) int64 {
	new := *ptr + delta
	*ptr = new
	return new
}
